package com.lbj.googleplay.googleplay100.ui.view;

import android.content.Context;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewGroup;

import com.lbj.googleplay.googleplay100.utils.UIUtils;

import java.util.ArrayList;

public class MyFLowLayout extends ViewGroup {


    private int mUsedWidth;//已使用的总宽度
    private int mHorizontalSpacing= UIUtils.dip2px(6);//水平间距
    private int mVerticalSpacing= UIUtils.dip2px(8);//垂直间距
    private Line mLine;//当前行对象
    private ArrayList<Line> mLineList = new ArrayList<>();//所有行的集合
    private static final int MAX_LINE = 100;//最大行数100行

    public MyFLowLayout(Context context) {
        super(context);
    }

    public MyFLowLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public MyFLowLayout(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        //遍历所有行对象,设置每行位置
        int left = l - getPaddingLeft();
        int top = t + getPaddingTop();

        for (int i = 0; i < mLineList.size(); i++) {
            Line line = mLineList.get(i);
            line.layout(left,top);
            //更新top值
            top += line.maxHeight + mVerticalSpacing;
        }


    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        //获取有效的宽高
      int width = MeasureSpec.getSize(widthMeasureSpec)-getPaddingLeft()-getPaddingRight();
      int height = MeasureSpec.getSize(heightMeasureSpec)-getPaddingTop()-getPaddingBottom();
        //获取宽高的模式
      int widthMode = MeasureSpec.getMode(widthMeasureSpec);
      int heightMode = MeasureSpec.getMode(heightMeasureSpec);
      //获取所有子控件数量
        int childCount = getChildCount();
        for (int i = 0; i < childCount; i++) {
            //获取一个子控件
            View childView = getChildAt(i);
            //设置其widthMeasureSpec,如果父控件的widthMode是确定,则子控件模式是包裹内容,否则子控件和父控件模式一致
            int childWidthMeasureSpec = MeasureSpec.makeMeasureSpec(width,(widthMode==MeasureSpec.EXACTLY)?MeasureSpec.AT_MOST:widthMode);
            int childHeightMeasureSpec = MeasureSpec.makeMeasureSpec(height,(heightMode==MeasureSpec.EXACTLY)?MeasureSpec.AT_MOST:heightMode);
            //开始测量
            childView.measure(childWidthMeasureSpec,childHeightMeasureSpec);
            //如果当前行对象为空,则创建一个行对象
            if (mLine==null){
                mLine = new Line();
            }
            //获取测量后的子控件宽度
            int childWidth = childView.getMeasuredWidth();
            mUsedWidth += childWidth;//已使用宽度增加一个当前子控件宽度

            if (mUsedWidth<width){//判断是否超出了边界
                mLine.addView(childView);//添加到行中
                mUsedWidth += mHorizontalSpacing;//加一个水平间距
                if (mUsedWidth>width){//加间距后如果超出边界,此时需要换行
                    if (!newLine()){
                        break;//如果创建行失败,就结束for循环
                    }
                }
            }else {
                //已超出边界
                //1.当前没有子控件,一旦添加子控件就超出边界(说明子控件很长)
                if (mLine.getChildCount()==0){
                    mLine.addView(childView);//强制添加到当前行
                    if (!newLine()){
                        break;
                    }
                }else {
                    //2.当前有子控件,一旦再添加控件则超出边界,此时应该直接换行
                    if (!newLine()){
                        break;
                    }
                    mLine.addView(childView);
                    mUsedWidth += childWidth+mHorizontalSpacing;//更新已使用宽度

                }
            }
        }
        //保存最后一行
        if (mLine!=null&&mLine.getChildCount()!=0&&!mLineList.contains(mLine)){
            mLineList.add(mLine);
        }
        int totalwidth = MeasureSpec.getSize(widthMeasureSpec);//控件总宽度
        //遍历行集合,计算控件总高度
        int totalHeight = 0;
        for (int i = 0; i < mLineList.size(); i++){
            Line line = mLineList.get(i);
            totalHeight += line.maxHeight;
        }
        //加上垂直间距
        totalHeight += (mLineList.size()-1)*mVerticalSpacing;
        //加上上下边距
        totalHeight += (getPaddingTop()+getPaddingBottom());
        //根据最新宽高来测量整体布局的大小,设置尺寸
        setMeasuredDimension(totalwidth,totalHeight);

    }

    //换行
    private boolean newLine(){
        //先把当前行保存上
        mLineList.add(mLine);
        if (mLineList.size()<MAX_LINE){//判断是否可以继续添加
            mLine = new Line();
            mUsedWidth = 0;//已使用宽度清零
            return true;//创建成果
        }
        return false;//创建失败
    }

    //每一行的对象封装
    class  Line{
        private int mTotalWidth;//当前所有控件总宽度
        private int maxHeight;//当前控件的高度,以最高的那个控件为准
        private ArrayList<View> mChildViewList = new ArrayList<>();//当前行所有子控件集合
       //添加一个子控件
        public void  addView(View view){
            mChildViewList.add(view);
            //总宽度增加
            mTotalWidth += view.getMeasuredWidth();

            int height = view.getMeasuredHeight();
            //修改行高度
            maxHeight = maxHeight < height ? height : maxHeight;

        }
        //获一行所有子控件数量
        public int getChildCount(){

            return mChildViewList.size();
        }
        //子控件位置设置
        public void layout(int left,int top){
            int childCount = getChildCount();
            //将剩余空间宽度平均分配给每个子控件
            //屏幕总有效宽度
            int validWidth = getMeasuredWidth()-getPaddingLeft()- getPaddingRight();
            //计算剩余宽度
            int surplusWidth = validWidth - mTotalWidth - (childCount-1)*mHorizontalSpacing;
            if (surplusWidth>=0){
                //有剩余空间
              int space = (int) (surplusWidth/childCount + 0.5f);
              //重新测量子控件
                for (int i = 0; i < childCount; i++) {
                    View childView = mChildViewList.get(i);
                    int measuredWidth = childView.getMeasuredWidth();
                    int measuredHeight = childView.getMeasuredHeight();
                    measuredWidth += space;//宽度增加
                    int widthSpec = MeasureSpec.makeMeasureSpec(measuredWidth, MeasureSpec.EXACTLY);
                    int heightSpec = MeasureSpec.makeMeasureSpec(measuredHeight, MeasureSpec.EXACTLY);
                    //重新测量控件
                    childView.measure(widthSpec,heightSpec);
                    //当控件比较矮是,需要居中展示,需要竖直方向上有一定的偏移
                    int topOffset = (maxHeight - measuredHeight)/2;
                    if (topOffset<0){
                        topOffset = 0 ;
                    }
                    //设置子控件位置
                    childView.layout(left,top+topOffset,left+measuredWidth,top+topOffset+measuredHeight);
                    //更新left值
                    left += measuredWidth+mHorizontalSpacing;

                }


            }else {
                //没有剩余空间,这个控件很长,占满正行
                View childView = mChildViewList.get(0);

                childView.layout(left,top, left+childView.getMeasuredWidth(),top+childView.getMeasuredHeight());



            }


        }
    }
}
